import type { AnchorPoint } from '../types';
import {
  Shape,
  type Bounds,
  type ShapeProperties,
  type StateProvider,
} from './Shape';

export class Circle extends Shape {
  public radius: number;
  public anchors: AnchorPoint[];

  constructor(
    x: number,
    y: number,
    color: string,
    lineWidth: number,
    stateProvider: StateProvider,
  ) {
    super(x, y, color, lineWidth, stateProvider);
    this.radius = 0;
    this.anchors = [];
  }

  public draw(ctx: CanvasRenderingContext2D): void {
    const scale = this.stateProvider?.getScale() ?? 1;
    ctx.strokeStyle = this.color;
    ctx.lineWidth = this.lineWidth / scale;
    ctx.beginPath();
    ctx.arc(this.x, -this.y, this.radius, 0, Math.PI * 2);
    ctx.stroke();

    if (this.selected) {
      this.drawSelection(ctx);
    }
  }

  public updateEnd(x: number, y: number): void {
    const dx = x - this.x;
    const dy = y - this.y;
    this.radius = Math.sqrt(dx * dx + dy * dy);
  }

  public contains(x: number, y: number): boolean {
    const scale = this.stateProvider?.getScale() ?? 1;
    const dx = x - this.x;
    const dy = y - this.y;
    const distance = Math.sqrt(dx * dx + dy * dy);
    return distance <= this.radius + 5 / scale;
  }

  public getProperties(): ShapeProperties {
    return {
      type: 'Circle',
      color: this.color,
      lineWidth: this.lineWidth,
      center: { x: this.x.toFixed(1), y: this.y.toFixed(1) },
      radius: this.radius.toFixed(1),
      diameter: (this.radius * 2).toFixed(1),
      circumference: (2 * Math.PI * this.radius).toFixed(1),
      area: (Math.PI * this.radius * this.radius).toFixed(1),
      position: {
        x: '',
        y: '',
      },
    };
  }

  public getBounds(): Bounds {
    return {
      left: this.x - this.radius,
      right: this.x + this.radius,
      top: this.y - this.radius,
      bottom: this.y + this.radius,
    };
  }

  public updateSpecificProperty(prop: string, value: string): void {
    if (prop === 'x') {
      this.x = Number.parseFloat(value);
    } else if (prop === 'y') {
      this.y = Number.parseFloat(value);
    } else if (prop === 'radius') {
      this.radius = Number.parseFloat(value);
    } else if (prop === 'diameter') {
      this.radius = Number.parseFloat(value) / 2;
    } else if (prop === 'circumference') {
      this.radius = Number.parseFloat(value) / (2 * Math.PI);
    } else if (prop === 'area') {
      this.radius = Math.sqrt(Number.parseFloat(value) / Math.PI);
    }
  }

  public updateProperty(prop: string, value: string): void {
    super.updateProperty(prop, value);
    this.updateSpecificProperty(prop, value);
  }

  public createAnchors(): void {
    this.anchors = [
      { x: this.x, y: this.y - this.radius, type: 'n' },
      { x: this.x + this.radius, y: this.y, type: 'e' },
      { x: this.x, y: this.y + this.radius, type: 's' },
      { x: this.x - this.radius, y: this.y, type: 'w' },
    ];
  }
}
